﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;

using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Abp.AspNetCore.Mvc.Controllers;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.IO.Extensions;
using Abp.Runtime.Session;
using Abp.UI;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Xugege.AbpExtension.Core.Extension.File;
using Xugege.AbpExtension.IO;
using Xugege.AbpExtension.Storage;
using Xugege.AbpExtension.Web.Core.Extension.Model;
using Abp.Extensions;
using Xugege.AbpExtension.Com.Helper;

namespace Xugege.AbpExtension.Web.Core.Extension.Controllers
{
    public class FileController : AbpController
    {
        private readonly long _singleFileSize = 1048576 * 3; //单个文件限制大小3M

        private readonly IAppFolderExtension _appFoldersExt;
        private readonly IAppFolders _appFolders;
        private readonly IBinaryObjectManager _binaryObjectManager;
        private readonly IUploadFileManager _uploadFileManager;
        private readonly IRepository<UploadFileRecord, long> _uploadFileRepository;

        public FileController(IAppFolderExtension appFoldersExt,
            IAppFolders appFolders,
            IBinaryObjectManager binaryObjectManager,
            IRepository<UploadFileRecord, long> uploadFileRepository,
            IUploadFileManager uploadFileManager)
        {
            _appFoldersExt = appFoldersExt;
            _appFolders = appFolders;
            _binaryObjectManager = binaryObjectManager;
            _uploadFileRepository = uploadFileRepository;
            _uploadFileManager = uploadFileManager;
            string fileUploadSize = ConfigurationManager.AppSettings["File.Upload.Size"];
            if (!string.IsNullOrEmpty(fileUploadSize))
            {
                if (!long.TryParse(fileUploadSize, out _singleFileSize))
                {
                    _singleFileSize = 1048576 * _singleFileSize;
                }
            }
            if (!System.IO.Directory.Exists(_appFolders.TempFileDownloadFolder))
            {
                System.IO.Directory.CreateDirectory(_appFolders.TempFileDownloadFolder);
            }
        }


        /// <summary>
        /// 获取文件相对路径
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Obsolete]
        [HttpGet]
        public FileResultViewModel GetFileTempPath(Guid id)
        {
            FileResultViewModel result = new FileResultViewModel();
            //string tmpRootDir =

            //    Server.MapPath(
            //        System.Web.HttpContext.Current.Request.ApplicationPath.ToString());//获取程序根目录


            //var fileInfo = _uploadFileRepository.FirstOrDefault(m => m.InstanceId == id);
            //if (fileInfo != null)
            //{
            //    var tempFilePath = Path.Combine(_appFolders.FileUploadPath, fileInfo.RealPath);
            //    if (!System.IO.File.Exists(tempFilePath))
            //    {
            //        return null;
            //    }
            //    result.Url = (_appFolders.FileUploadPath + "\\" + fileInfo.RealPath).Replace(tmpRootDir, "");

            //}
            return result;
        }

        /// <summary>
        /// 获取图片base64
        /// </summary>
        /// <param name="id">上传图片的guid标识</param>
        /// <returns></returns>

        [HttpGet]
        public FileResultViewModel GetImageDataUrl(Guid id)
        {
            FileResultViewModel result = new FileResultViewModel();
            try
            {
                
                var fileInfo = _uploadFileRepository.FirstOrDefault(m => m.InstanceId == id);
                if (fileInfo != null)
                {

                    var fs = new System.IO.FileStream(_appFoldersExt.FileUploadPath + "\\" + fileInfo.RealPath,
                        FileMode.Open,
                        FileAccess.Read);
                    var fileReader = new BinaryReader(fs);
                    byte[] bytes = fileReader.ReadBytes((int)fs.Length);
                    string dataUrl = Convert.ToBase64String(bytes);
                    result.Url = "data:" + fileInfo.FileType + ";base64," + dataUrl;

                    fileReader.Close();
                    fs.Close();

                }
                else
                    result.Url = "";
            }
            catch (Exception)
            {
                //ignore
            }

            return result;
        }


        /// <summary>
        /// 上传(单个)文件(附件)
        /// </summary>
        /// <returns></returns>
        [UnitOfWork]
        public virtual async Task<JsonResult> UploadAccessory()
        {
            IList<string> fileIds = new List<string>();
            try
            {
                var upFile = Request.Form.Files.First();
                //Request.Form["image"]
                #region 验证

                if (upFile == null)
                {
                    throw new UserFriendlyException("文件不能为空");
                }
                if (upFile.Length > _singleFileSize)
                {
                    throw new UserFriendlyException("文件超出限制大小");
                }

                #endregion


                byte[] fileBytes;
                using (var stream = upFile.OpenReadStream())
                {
                    fileBytes = stream.GetAllBytes();
                }

                #region 路径

                //save file
                var fileInstanceId = Guid.NewGuid();
                var filePath = GetFilePath();

                var tempFileName = upFile.FileName;
                if (!Directory.Exists(filePath))
                {
                    Directory.CreateDirectory(filePath);
                }
                var tempFilePath = Path.Combine(filePath, tempFileName);

                AppFileHelper.DeleteFilesInFolderIfExists(filePath, tempFileName);

                #endregion

                #region 保存

                System.IO.File.WriteAllBytes(tempFilePath, fileBytes);
                string fileRelativePath = _appFoldersExt.GetRelativePath(tempFilePath);
                await _uploadFileManager.Add(new UploadFileRecord()
                {
                    InstanceId = fileInstanceId,
                    FileName = upFile.FileName,
                    FileSize = upFile.Length,
                    FileType = upFile.ContentType,
                    RealPath = fileRelativePath,
                    Uploader = AbpSession.GetUserId(),
                    UploadTime = DateTime.Now
                });

                #endregion

                fileIds.Add(fileInstanceId.ToString());
            }
            catch (Exception ex)
            {
                throw new UserFriendlyException(ex.Message);

            }
            return await Task.FromResult(Json(fileIds));
        }

        /// <summary>
        /// 上传图片 for app
        /// content-type multipart/form-data
        /// header --> {file-url,file-type,mime-type}
        /// file-type --> 0 图片 1 视频 2 其他
        /// 
        /// </summary>
        /// <returns></returns>
        [UnitOfWork]
        public virtual async Task<JsonResult> Upload4App()
        {
            string fileId = "";
            try
            {

                using (var buffer = new MemoryStream())
                {
                    Request.Body.CopyTo(buffer);
                    if (buffer.Length > 0)
                    {
                        var fileInstanceId = Guid.NewGuid();
                        string fileMimeType = "";
                        string fileRelativePath = "";
                        var fileUrl = Request.Headers["file-url"];
                        string fileName = Path.GetFileName(fileUrl);
                        string fileType = Request.Headers["file-type"];
                        var filePath = GetFilePath();
                        var tempFilePath = Path.Combine(filePath, fileName);
                        fileType = fileType.Trim();

                        if (!Directory.Exists(filePath))
                        {
                            Directory.CreateDirectory(filePath);
                        }
                        if (fileType == "0")
                        {
                            //图片
                            var fileImage = Image.FromStream(buffer);
                            fileMimeType = CheckImage(fileImage);

                            AppFileHelper.DeleteFilesInFolderIfExists(filePath, fileInstanceId.ToString());
                            fileImage.Save(tempFilePath, fileImage.RawFormat);

                        }
                        else
                        {
                            fileMimeType = Request.Headers["mime-type"];
                            FileStream fs = System.IO.File.Create(tempFilePath, (int)buffer.Length);
                            await fs.WriteAsync(buffer.GetBuffer(), 0, (int)buffer.Length);
                            //await buffer.CopyToAsync(fs);
                            await fs.FlushAsync();
                            fs.Dispose();
                            fs.Close();
                        }

                        fileRelativePath = _appFoldersExt.GetRelativePath(tempFilePath);
                        await _uploadFileManager.Add(new UploadFileRecord()
                        {
                            InstanceId = fileInstanceId,
                            FileName = fileInstanceId.ToString(),
                            FileSize = buffer.Length,
                            FileType = fileMimeType,
                            RealPath = fileRelativePath,
                            Uploader = AbpSession.GetUserId(),
                            UploadTime = DateTime.Now
                        });
                        fileId = fileInstanceId.ToString();
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }


            return await Task.FromResult(Json(new
            {
                id = fileId
            }));
        }

        private string GetFilePath()
        {

            var timestring = StringHelper.CreateIdByGuidAndTime();
            var tenantId = AbpSession.TenantId;
            string filePath;
            if (tenantId.HasValue)
            {
                filePath = _appFoldersExt.FileUploadPath + "/" + AbpSession.TenantId + "/" +
                           AbpSession.GetUserId() + "/" + timestring;
            }
            else
            {
                filePath = _appFoldersExt.FileUploadPath + "/" + timestring;
            }
            return filePath;
        }

        /// <summary>
        /// 返回文件类型
        /// </summary>
        /// <param name="img"></param>
        /// <returns></returns>
        private string CheckImage(Image img)
        {
            var acceptedFormats = new List<ImageFormat>
            {
                ImageFormat.Jpeg, ImageFormat.Png, ImageFormat.Gif
            };
            if (!acceptedFormats.Contains(img.RawFormat))
            {
                throw new ApplicationException("Uploaded file is not an accepted image file !");
            }
            return "image/" + acceptedFormats[acceptedFormats.IndexOf(img.RawFormat)].ToString();
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="id">上传文件Guid标识</param>
        /// <returns></returns>
        [HttpGet]
        public ActionResult Download(Guid id)
        {
            try
            {
                var fileInfo = _uploadFileRepository.FirstOrDefault(m => m.InstanceId == id);
                if (fileInfo != null)
                {
                    string filePath = _appFoldersExt.WebRootPath + "\\" + fileInfo.RealPath;
                    if (!System.IO.File.Exists(filePath)) return null;
                    var allBytes = System.IO.File.ReadAllBytes(filePath);
                    return File(allBytes, fileInfo.FileType, fileInfo.FileName);
                }

            }
            catch (Exception)
            {
                //ignore
            }
            return null;
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="path">文件相对路径</param>
        /// <param name="fileType">文件类型</param>
        /// <returns></returns>
        public ActionResult Download(string path, string fileType = "")
        {
            try
            {
                string fileName = Path.GetFileName(path);
                string filePath = _appFoldersExt.WebRootPath + "\\" + path;
                if (!System.IO.File.Exists(filePath)) return null;
                var allBytes = System.IO.File.ReadAllBytes(filePath);
                return File(allBytes, fileType.IsNullOrEmpty() ? "text/plain" : fileType, fileName);

            }
            catch (Exception)
            {
                //ignore
            }
            return null;
        }


    }
}
